﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleData.ObjectModel.Collections
{
	public class DocumentValuesDictionary : IDictionary<FieldName, object>, INamespaceContainer
	{


		public DocumentValuesDictionary()
			: this( null )
		{ }

		public DocumentValuesDictionary( NamespaceScope ns )
		{
			this.InnerDictionary = new Dictionary<FieldName, object>( new FieldNameEqualityComparer() );
			this.UsingNamespace = ns;
		}

		/// <summary>
		/// Obtém ou define o dicionário interno utilizado 
		/// para armazenar os valores do documento
		/// </summary>
		protected Dictionary<FieldName, object> InnerDictionary
		{
			get;
			private set;
		}


		/// <summary>
		/// Obtém ou define o namespace que está sendo utilizado por padrão 
		/// para acessar os campos do documento
		/// </summary>
		public NamespaceScope UsingNamespace
		{
			get;
			set;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public object this[ string key ]
		{
			get { return this[ FieldName.Parse( this.EnsureFullName( key ) ) ]; }
			set { this[ FieldName.Parse( this.EnsureFullName( key ) ) ] = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public bool Remove( string key )
		{
			return this.Remove( FieldName.Parse( this.EnsureFullName( key ) ) );
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <returns></returns>
		public bool TryGetValue( string key, out object value )
		{
			return this.TryGetValue( FieldName.Parse( this.EnsureFullName( key ) ), out value );
		}
		
		#region [ IDicionary<FieldName, Object> Members ]


		public void Add( FieldName key, object value )
		{
			this.InnerDictionary.Add( key, value );
		}

		public bool ContainsKey( FieldName key )
		{
			return this.InnerDictionary.ContainsKey( key );
		}

		public ICollection<FieldName> Keys
		{
			get { return this.InnerDictionary.Keys; }
		}

		public bool Remove( FieldName key )
		{
			return this.InnerDictionary.Remove( key );
		}

		public bool TryGetValue( FieldName key, out object value )
		{
			return this.InnerDictionary.TryGetValue( key, out value );
		}

		public ICollection<object> Values
		{
			get { return this.InnerDictionary.Values; }
		}

		public object this[ FieldName key ]
		{
			get
			{
				return this.InnerDictionary[ key ];
			}
			set
			{
				this.InnerDictionary[ key ] = value;
			}
		}

		public void Add( KeyValuePair<FieldName, object> item )
		{
			this.InnerDictionary.Add( item.Key, item.Value );
		}

		public void Clear()
		{
			this.InnerDictionary.Clear();
		}

		public bool Contains( KeyValuePair<FieldName, object> item )
		{
			return this.InnerDictionary.ContainsKey( item.Key );
		}

		public void CopyTo( KeyValuePair<FieldName, object>[] array, int arrayIndex )
		{
			this.CopyTo( array, arrayIndex );
		}

		public int Count
		{
			get { return this.InnerDictionary.Count; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove( KeyValuePair<FieldName, object> item )
		{
			return this.Remove( item.Key );
		}

		public IEnumerator<KeyValuePair<FieldName, object>> GetEnumerator()
		{
			return this.InnerDictionary.GetEnumerator();
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		#endregion

		#region [ class FieldNameEqualityComparer ]

		/// <summary>
		/// 
		/// </summary>
		private sealed class FieldNameEqualityComparer : IEqualityComparer<FieldName>
		{
			public bool Equals( FieldName x, FieldName y )
			{
				return x.Equals( y );
			}

			public int GetHashCode( FieldName obj )
			{
				return obj.GetHashCode();
			}
		}

		#endregion

	}
}
